package demo.game.chess.client.ui;

import java.util.Arrays;

import com.google.gwt.core.client.JsArrayInteger;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.ListBox;

import demo.game.chess.common.AbstractChessPiece;
import demo.game.chess.common.ChessCell;
import demo.game.chess.common.ChessMove;
import demo.game.chess.common.EnumChessColor;
import demo.game.chess.common.MoveException;

public class ComputerPlayMoveListener implements IChessMoveListener {

	static final EnumChessColor HUMAN = EnumChessColor.white;

	private final ListBox selectLevel = new ListBox();

	public ComputerPlayMoveListener() {

	}

	@Override
	public void afterUndoMove(final AbstractChessUI chessUI) {
		if (chessUI.getManager().getCurrentBoard().getCurrentTurn() != HUMAN) {
			// go back a pair of moves : computer's and user's
			goback();
			// undo the user's turn
			chessUI.undoLastMove();
		}
	}

	@Override
	public void afterConfirmMove(final AbstractChessUI chessUI,
			final AbstractChessPiece movingPiece, final ChessMove move) {
		if (movingPiece.getColor() == HUMAN) {
			chessUI.showInfo("Computer is thinking");

			Timer t = new Timer() {

				@Override
				public void run() {
					JsArrayInteger computerMoveArray = move(move
							.getOriginCell().getRow(), move.getOriginCell()
							.getColumn(), move.getTargetCell().getRow(), move
							.getTargetCell().getColumn());

					if (computerMoveArray == null
							|| computerMoveArray.length() == 0) {
						chessUI.showInfoWarning("Error in computer move");
					} else {
						ChessMove m = null;
						try {
							m = chessUI.getManager().getCurrentBoard()
									.createValidMove(
											new ChessCell(computerMoveArray
													.get(0), computerMoveArray
													.get(1)),
											new ChessCell(computerMoveArray
													.get(2), computerMoveArray
													.get(3)));

							if (null != m) {
								chessUI.confirmMove(m);
							} else {
								chessUI
										.showInfoWarning("Error in computer move "
												+ Arrays
														.asList(computerMoveArray));
							}
						} catch (MoveException e) {

							chessUI.showInfoWarning("Error in computer move "
									+ m + e.getMessage());
						}

					}
				}

			};

			t.schedule(1000);

		}
	}

	@Override
	public void beforeUndoMove(final AbstractChessUI abstractChessUI) {

	}

	@Override
	public void beforeConfirmMove(final AbstractChessUI chessUI,
			final AbstractChessPiece movingPiece, final ChessMove move) {

	}

	private native void goback() /*-{
		return $wnd.p4wn_goback();
	}-*/;

	private native JsArrayInteger move(int originX, int originY, int targetX,
			int targetY) /*-{
		return $wnd.p4wn_playerMove(originX, originY, targetX, targetY);
	}-*/;

	public native void setLevel(int level) /*-{
		$wnd.p4wn_level = level;
	}-*/;

}
